package com.gsk.europepharma.salesReport.struts.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.hibernate.Query;
import org.hibernate.Session;

import com.gsk.europepharma.salesReport.hibernate.dao.tbSpBoSRSectoDAO;

/**
 * Gestion des donnees pour l'affichage du tableau avec tous les produits à tous les niveaux.
 */
public class DataTable extends Action {
	
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
	
		// Variables de session
		HttpSession sessionObject = request.getSession();
		Integer cs_adm_pdt = (Integer) sessionObject.getAttribute("cs_adm_pdt");
		Integer cs_adm_rgpt = (Integer) sessionObject.getAttribute("cs_adm_rgpt");
		Integer cs_adm_prstn = (Integer) sessionObject.getAttribute("cs_adm_prstn");
		Integer cs_network = (Integer) sessionObject.getAttribute("cs_network");
		Integer cs_month = (Integer) sessionObject.getAttribute("cs_month");
		// Fin de session
        
		String filters = request.getParameter("filters");
		
		String source = request.getParameter("source");
		Integer CS_SRC = Integer.parseInt(source);
		// String unite = request.getParameter("unite");
		String periode = request.getParameter("periode");
		
		boolean initializedSessionAttributes = false;
		if (sessionObject.getAttribute("source") == null || sessionObject.getAttribute("period") == null) {
			initializedSessionAttributes = true;
		} else {
			if (!(sessionObject.getAttribute("source").equals(source) && sessionObject.getAttribute("source").equals(source))) {
				initializedSessionAttributes = true;
			}
		}
		sessionObject.setAttribute("source", source);
		sessionObject.setAttribute("period", periode); // ???
		
		Set<String> filtersSet = new HashSet<String>();
		if (filters != null && !filters.equals("")) {
			String tabFilter[] = filters.split(";");
			for (String filter : tabFilter) {
				if (!filter.equals("")) {
					filtersSet.add(filter.substring(1, filter.length()));
				}
			}
		}
		
		tbSpBoSRSectoDAO salesDAO = new tbSpBoSRSectoDAO();
		Session session = salesDAO.getSession();
		
		String products = request.getParameter("products");
		String firstProductName = "";
		
		TreeMap<String, Iterator> iterators = new TreeMap<String, Iterator>();
        
		int j =1;
        
        if (products != null && products != "") {
        	String tabProduts[] = products.split(";");
        	firstProductName = tabProduts[0];
        	// For each product 
        	for (String product : tabProduts) {
        		if (!product.equals("")) {
        			//if (sessionObject.getAttribute("req" + product) == null || initializedSessionAttributes) {
        				Query req = session.getNamedQuery(salesDAO.QUERY_TABLE);
        				req.setInteger("cs_adm_pdt", cs_adm_pdt);
        				req.setInteger("cs_adm_rgpt", cs_adm_rgpt);
        				j++;
        				req.setInteger("cs_adm_prstn", cs_adm_prstn);
        				req.setInteger("CS_SRC", CS_SRC);
        				req.setInteger("cs_network", cs_network);
        				req.setInteger("cs_month", cs_month);
        				ArrayList result = new ArrayList(req.list());
        				sessionObject.setAttribute("req" + product, result);
        			//}
        			Iterator iter = ((ArrayList) sessionObject.getAttribute("req" + product)).iterator();
        			iterators.put(product, iter);
        		}
        	}
        }
		
		String zoneCourante = "";
		String regionCourante = "";
		String secteurCourant = "";
		String ugaCourant = "";
		String ugpCourant = "";
		TreeMap<String, TreeMap<String, TreeMap<String, TreeMap<String, List<String>>>>> complexObject = new TreeMap<String, TreeMap<String, TreeMap<String, TreeMap<String, List<String>>>>>(); 
		Map<String, JSONObject> mapData = new HashMap<String, JSONObject>();
		
		while (iterators.get(firstProductName).hasNext()) {
			Object[] firstProduct = (Object[]) iterators.get(firstProductName).next();
			
			JSONObject jsonObject = new JSONObject();
			
			jsonObject.put("market", firstProduct[2].toString());
			jsonObject.put(firstProductName, firstProduct[3].toString());
			jsonObject.put(firstProductName + "Pm", firstProduct[4].toString() + "%");
			jsonObject.put(firstProductName + "Delta", firstProduct[5].toString());
			
			if (products != null && products != "") {
	        	String tabProduts[] = products.split(";");
	        	int i = 0;
	        	// For each product 
	        	for (String product : tabProduts) {
	        		if (!product.equals("") && i != 0) {
	        			Object[] otherProduct = (Object[]) iterators.get(product).next();
	        			if (firstProduct[0].toString().equals("UGP")) {
	        				jsonObject.put(product, "");
	        			} else {
	        				jsonObject.put(product, otherProduct[3].toString());
	        			}
	        			jsonObject.put(product + "Pm", otherProduct[4].toString() + "%");
	        			jsonObject.put(product + "Delta", otherProduct[5].toString());
	        		}
	        		i++;
	        	}
			}
			
			if (firstProduct[0].toString().equals("ZONE")) {
				zoneCourante = firstProduct[1].toString();
				jsonObject.put("secto", zoneCourante);
				jsonObject.put("typeSecto", "ZONE");
				mapData.put(zoneCourante, jsonObject);
				complexObject.put(zoneCourante, new TreeMap<String, TreeMap<String, TreeMap<String, List<String>>>>());
			} else if (firstProduct[0].toString().equals("REGION")) {
				regionCourante = firstProduct[1].toString();
				jsonObject.put("secto", regionCourante);
				jsonObject.put("typeSecto", "REGION");
				mapData.put(regionCourante, jsonObject);
				complexObject.get(zoneCourante).put(regionCourante, new TreeMap<String, TreeMap<String, List<String>>>());
			} else if (firstProduct[0].toString().equals("SECTEUR")) {
				secteurCourant = firstProduct[1].toString();
				jsonObject.put("secto", secteurCourant);
				jsonObject.put("typeSecto", "SECTEUR");
				mapData.put(secteurCourant, jsonObject);
				complexObject.get(zoneCourante).get(regionCourante).put(secteurCourant, new TreeMap<String, List<String>>());
			} else if (firstProduct[0].toString().equals("UGA")) {
				ugpCourant = firstProduct[1].toString();
				jsonObject.put("secto", ugpCourant);
				jsonObject.put("typeSecto", "UGA");
				mapData.put(ugaCourant, jsonObject);
				complexObject.get(zoneCourante).get(regionCourante).get(secteurCourant).put(ugaCourant, new ArrayList<String>());
			} else if (firstProduct[0].toString().equals("UGP")) {
				ugpCourant = firstProduct[1].toString();
				jsonObject.put("secto", ugpCourant);
				jsonObject.put("market", "");
				jsonObject.put("typeSecto", "UGP");
				jsonObject.put(firstProductName, "");
				mapData.put(ugpCourant, jsonObject);
				complexObject.get(zoneCourante).get(regionCourante).get(secteurCourant).get(ugaCourant).add(ugpCourant);
			}
		}
		
		HashMap hm = new HashMap();
		
		JSONObject root = new JSONObject();
		root.put("expanded", true);
		JSONArray childrenRoot = new JSONArray();
		
		for (Map.Entry<String, TreeMap<String, TreeMap<String, TreeMap<String, List<String>>>>> z : complexObject.entrySet()) {
			
			JSONObject zone = new JSONObject();
			zone = mapData.get(z.getKey());
			
			JSONArray childrenZone = new JSONArray();
			
			for (Map.Entry<String, TreeMap<String, TreeMap<String, List<String>>>> r : z.getValue().entrySet()) {
				
				JSONObject region = new JSONObject();
				region = mapData.get(r.getKey());
				
				JSONArray childrenRegion = new JSONArray();
				
				for (Map.Entry<String, TreeMap<String, List<String>>> s : r.getValue().entrySet()) {
					
					JSONObject secteur = new JSONObject();
					secteur = mapData.get(s.getKey());
					
					JSONArray childrenSecteur = new JSONArray();
					
					for (Map.Entry<String, List<String>> u : s.getValue().entrySet()) {
						
						JSONObject uga = new JSONObject();
						uga = mapData.get(u.getKey());
						
						JSONArray childrenUga = new JSONArray();
						
						for (String ug : u.getValue()) {
							
							JSONObject ugp = new JSONObject();
							ugp = mapData.get(ug);
							ugp.put("leaf", true);
							
							childrenUga.add(ugp);
							
						}
						
						uga.put("children", childrenUga);
						
						childrenSecteur.add(uga);
						
					}
					
					secteur.put("children", childrenSecteur);
					
					childrenRegion.add(secteur);
					
				}
				
				region.put("children", childrenRegion);
				
				childrenZone.add(region);
				
			}
			
			zone.put("children", childrenZone);
			
			childrenRoot.add(zone);
		}
		
		root.put("children", childrenRoot);
		
		hm.put("json", root);
		
		JSONObject json = JSONObject.fromObject(hm);
		
		response.addHeader("Content-Type", "application/json");
        response.getOutputStream().write(json.toString().getBytes("UTF-8"));
        response.getOutputStream().flush();
		
		return null;
	}
	
}
